library ieee;
use std.textio.all;
use ieee.std_logic_textio.all; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all; 
use ieee.std_logic_unsigned.all;  
use work.dec_pkg.all;
entity tb_dec_top is
end tb_dec_top ;  

architecture rtl of tb_dec_top  is

   component dec_chip is 
    port(
    rst	   :in std_ulogic;
    clk_l 	   :in std_ulogic;               --clk_l low frequency, clk_h high frequency
    clk_r       :in std_ulogic;
    m1_en	   :in std_ulogic;		 --mem1
    cmd1       :in std_ulogic;               --mem1 (wr='1' | rd='0')
    addr1	   :in word16;			 --mem1	
    data1      :in word32;		 	 --mem1	
    ack1       :out std_ulogic;              --mem1
    m2_en	   :in std_ulogic;		 --mem2
    cmd2       :in std_ulogic;               --mem2 (wr='1' | rd='0')
    addr2	   :in word16;			 --mem2	
    data2      :out word16;			 --mem2	
    ack2       :out std_ulogic;              --mem2
    wb_clk    :in std_ulogic;                   --wishbone interface 
    wb_en     :in std_ulogic;
    wb_addr   :in word16;
    wb_data   :in word16;                      --wishbone interface 
    irq        :out std_ulogic ;             -- one frame ended (interruption)
    LKDT       :out std_ulogic;
    debug_en : in std_ulogic;
    debug_clk : out std_ulogic;
    debug_sel : in std_ulogic;
    debug_data: out std_ulogic_vector(31 downto 0);
		 	
    N     : in std_ulogic_vector(3 downto 0);
    M     : in std_ulogic_vector(6 downto 0);
    OD    : in std_ulogic_vector(1 downto 0);
    BP    : in std_ulogic;		
    PDRST : in std_ulogic
    );
  end component;
  
  
  
  
  signal rst :std_ulogic ;
  signal clk_l,clk_h :std_ulogic:= '0';
  signal m1_en :std_ulogic;
  signal cmd1 :std_ulogic;
  signal addr1,addrx1,addry1 : word32;
  signal data1 : word32;
  signal ack1 : std_ulogic;
  signal  m2_en : std_ulogic;
  signal cmd2 :std_ulogic;
  signal addr2 :word32;
  signal data2 :word32;
  signal ack2 :std_ulogic;
  signal irq,enable2,enable3,enable4 : std_ulogic;
  signal b:std_ulogic;
  signal cal_len : std_ulogic_vector(15 downto 0);
  signal ux,sigma,chan :std_ulogic_vector(15 downto 0);
	constant clock1: TIME:=20ns;  --21.008MHz clock
  constant clock2: TIME:=40 ns;	  --100MHz clock
  signal req_frame : word32 := "00000000000000000000000110010000";
 	signal req_frame1 : word32 := "00000000000000000000000110010001";	
 	signal enable:std_ulogic;	
 	signal w_cnt: word32;
 	signal wb_clk :std_ulogic := '0' ;
 	signal wb_en :std_ulogic := '0';
 	signal wb_temp:std_ulogic_vector(15 downto 0);
 	signal wb_addr : word32;
 	signal wb_data : word32;
 	signal LKDT : std_ulogic;
 	 signal N     :  std_ulogic_vector(3 downto 0);
   signal  M     :  std_ulogic_vector(6 downto 0);
   signal  OD    :  std_ulogic_vector(1 downto 0);
   signal  BP    :  std_ulogic;		
   signal  PDRST :  std_ulogic;
   signal dataxx1 : word32;
   signal addrxx1 : word16;
   signal ack1x,ack1xx : std_ulogic;
   signal debug_en ,debug_sel,debug_clk: std_ulogic;
   signal debug_cup :std_ulogic_vector(15 downto 0);
   signal debug_data :std_ulogic_vector(31 downto 0);
			begin   
			  M <= "0010000";
			  N <= "0010";
			  PDRST <= '0';
			  OD <= "01";
			  BP <= '0';
			dec: dec_chip port map(
			rst => rst,
			clk_l => clk_l,
			clk_r =>clk_h,
			m1_en =>m1_en,
			cmd1 => cmd1,
			addr1=>addrxx1(15 downto 0),
			data1 => dataxx1,
			ack1 => ack1,
			m2_en =>m2_en ,
			cmd2 => cmd2,
			addr2=>addr2(15 downto 0) ,
			data2 => data2(15 downto 0),
			ack2=>ack2,
			wb_clk => wb_clk ,
			wb_en => wb_en ,
			wb_addr=> wb_addr(15 downto 0),
			wb_data=> wb_data(15 downto 0),
			irq=>irq,
			debug_clk => debug_clk,
			debug_en => debug_en ,
      debug_sel => debug_sel,
      debug_data => debug_data,
			LKDT   => LKDT,
      N     => N,
      M    => M,
      OD    => OD,
      BP    => BP,
      PDRST => PDRST
			); 
	---------------clk generator ------------------------------		
clk1_process: process (clk_l) 
					begin     
					clk_l<= NOT clk_l after clock1/2;
				end process;
clk2_process: process (clk_h) 
					begin     
					clk_h<= NOT clk_h after clock2/2;
				end process;	
wb_clk_process :process (wb_clk)
begin 
    wb_clk <= not wb_clk after clock1/2;
end process;



process(clk_l)
  begin 
    if clk_l 'event and clk_l = '1' then 
      enable2 <= ack2;
      ack1x <= ack1; 
    end if;
  end process;
  process(clk_l)
  begin 
    if clk_l 'event and clk_l = '1' then 
      enable3 <= enable2;
      ack1xx <= ack1x;
    end if;
  end process;
   process(clk_l)
  begin 
    if clk_l 'event and clk_l = '1' then 
      enable4 <= enable3;
    end if;
  end process;
  process(clk_l)
  begin 
    if clk_l 'event and clk_l = '1' then 
      enable <= enable4;
      addrxx1 <= addrx1(15 downto 0);
      dataxx1 <= data1; 
    end if;
  end process;
  
debug_en <= '1' ;
debug_sel <= '1';
wb_en <= '1' ,'0' after clock1 *32774;
rst <='0', '1' after  clock1 * 32775;  
cmd1 <= '0' ,'1' after clock1 * 32776;
m1_en <= cmd1;
b <= transform(data2(15 downto 0));



process(debug_clk,debug_en)
  FILE FILEOUT: TEXT OPEN WRITE_MODE IS "debugdatay.txt";  
  variable x :std_logic_vector(31 downto 0);
  variable buf:LINE;
 -- variable y :std_ulogic_vector(31 downto 0);
  begin 
     x := std_logic_vector(debug_data);  
    if debug_clk'event and debug_clk = '1'  then 
       write(BUF,x);
			 writeline(FILEOUT,BUF);
			end if;
end process; 
process (clk_l, irq) 
  begin 
    if clk_l'event and clk_l = '1' then 
      if irq = '1' then 
      cmd2 <= '1';
     m2_en <=  '1';
   else 
     cmd2 <= cmd2;
     m2_en <= m2_en ;
   end if ;
 end if ;
 end process;
 --------------wb addr generator----------------------------------
 process (wb_clk , wb_en )
   begin 
     if wb_en = '0' then 
        w_cnt <= (others => '0' );
      elsif wb_clk'event and wb_clk = '1' then 
        w_cnt <=to_stdulogicvector(to_stdlogicvector(w_cnt) + 1);
      end if;
    end process;
    process (wb_clk)
      begin 
        if wb_clk'event and wb_clk = '1' then 
           wb_addr <= w_cnt;
          end if ;
  end process ;
-------------------------------------------------------------

----------------------wb_data generator------------------------------
wb_data <= "0000000000000000" & wb_temp;
process_wb:process(wb_en,wb_clk)
        file filein: text open read_mode is "reg.txt";    
        variable buf:LINE;
         variable x:std_ulogic_vector(15 downto 0);	
          begin
          if wb_en='0' then
              x :=(others=>'0');
          elsif wb_clk'event and wb_clk=  '1' then 
                if not (endfile(filein)) then
                     readline(filein,buf);
                     read(buf,x);
                     wb_temp <= x;
                      else
                        assert false
                        report"end of file!"
                        severity note;
                    end if;    
                end if;
      end process;
    

process(clk_l)
begin
if clk_l'event and clk_l = '1' then  
addrx1 <= addr1 ;
end if ;
end process;
process (clk_l,rst)
  begin 
    if rst = '0' then 
       addr2 <= (others => '0');
  elsif clk_l'event and clk_l = '1' then 
       if m2_en = '1' and ack2 = '1' then 
           if addr2 = conv_std_ulogic_vector((to_int(req_frame)  ) ,32) then 
              addr2 <= (others => '0');
          else 
            addr2 <= conv_std_ulogic_vector((to_int(addr2) + 1),32);
          end if ;
        else 
          addr2 <= (others => '0');
        end if;
      end if;
    end process;
    
process (clk_l,rst,m1_en,ack1)
begin 
if rst = '0' then 
    addr1 <= (others=> '0'); 
  elsif ack1xx = '0' then 
    addr1 <= (others=> '0');
    elsif  m1_en = '1' and ack1xx = '1' then   
         if clk_l'event and clk_l = '1' then     
            if addr1 = req_frame and  ack1xx = '0' then 
               addr1 <= (others=> '0');
             elsif addr1 = req_frame and  ack1xx = '1' then 
               addr1 <= addr1;
             else 
            addr1 <= conv_std_ulogic_vector((to_int(addr1) + 1),32); 
           end if;
         end if;
    else 
        addr1 <= (others=> '0');
      end if;
   
  end process;
  
            
 

--------------------------------------------------------read u---------------------------------------
process_inu:process(clk_l,rst)
				file filein: text open read_mode is "cupdata_u.txt";    
				variable buf:LINE;
		   	variable x:std_ulogic_vector(15 downto 0);	
					begin
					if rst='0' then
						  ux <=(others=>'0');
					elsif clk_l'event and clk_l=  '1' then 
					   if m1_en = '1' and ack1xx = '1' then 
					     if addr1 = conv_std_ulogic_vector((to_int(req_frame) ) ,32) then 
					       ux <= (others => '0');
					       else
						         if not (endfile(filein)) then
							         readline(filein,buf);
							         read(buf,x);
							         ux <= x;
						          else
							          assert false
								        report"end of file!"
							          severity note;
                    end if;
                  
                end if;
						else 
						  ux <=(others=>'0');
						  end if;
					end if;
			end process;
	---------------------------------------------------read chan--------------------------------------------			
 process_inchan:process(clk_l,rst)
                file filein: text open read_mode is "cupdata_chanx.txt";    
                variable buf:LINE;
                 variable x:std_ulogic_vector(15 downto 0);	
                  begin
                  if rst='0' then
                      chan <=(others=>'0');
                  elsif clk_l'event and clk_l=  '1' then 
                     if m1_en = '1' and ack1xx = '1' then 
                       if addr1 =conv_std_ulogic_vector((to_int(req_frame)  ) ,32) then 
                         chan <= (others => '0');
                          else 
                             if not (endfile(filein)) then
                               readline(filein,buf);
                               read(buf,x);
                               chan<=x;
                             else
                                assert false
                                report"end of file!"
                                severity note;
                            end if;
                        end if;
                    else 
                      chan <=(others=>'0');
                    end if;
                  end if;
              end process;
-----------------------------------------------------------------------------------------------
process_insigma:process(clk_l,rst)
			file filein: text open read_mode is "cupdata_sigma.txt";    
			variable buf:LINE;
			variable x:std_ulogic_vector(15 downto 0);	
				begin
				if rst='0' then
					sigma<=(others => '0');
				elsif clk_l'event and clk_l='1' then
				   if m1_en = '1' and ack1xx = '1'  then
				      if  addr1 = conv_std_ulogic_vector((to_int(req_frame)) ,32) then   
					       if not (endfile(filein)) then
						         readline(filein,buf);
						         read(buf,x);
						         sigma<=x; 
					       else
						          assert false
							        report"end of file!"
						          severity note;
					        end if;
				    	else 
						  sigma <= (others => '0');
						  end if;
						  else 
						      sigma <= (others => '0');
				end if;
				end if;
			end process;
			
	process_incal_len:process(clk_l,rst)
			file filein: text open read_mode is "callen.txt";    
			variable buf:LINE;
			variable x:std_ulogic_vector(15 downto 0);	
				begin
				if rst='0' then
					cal_len<=(others => '0');
				elsif clk_l'event and clk_l='1' then
				   if m1_en = '1' and ack1 = '1'  then
				      if  addr1 = conv_std_ulogic_vector((to_int(req_frame)  ) ,32) then   
					       if not (endfile(filein)) then
						         readline(filein,buf);
						         read(buf,x);
						         cal_len <= x; 
					       else
						          assert false
							        report"end of file!"
						          severity note;
					        end if;
				    	else 
						  cal_len <= (others => '0');
						  end if;
						  else 
						      cal_len <= (others => '0');
				end if;
				end if;
			end process;		
			
			
datat1in:process (addrx1,ack1xx,chan,ux,sigma,cal_len)
begin 
  if ack1xx = '1' then 
  if addrx1  = req_frame then 
    data1 <= cal_len&sigma;
  else 
    data1 <= chan & ux;
  end if;
else 
   data1 <= data1;
   end if;
end process;

		PROCESS_OUTDATA:PROCESS(clk_l,enable)
				FILE FILEOUT: TEXT OPEN WRITE_MODE IS "outdata.txt";    
				VARIABLE BUF:LINE;
				VARIABLE X:STD_uLOGIC_vector(15 downto 0);	
					BEGIN
					if enable = '1' then 
					IF clk_l'EVENT AND clk_l='1' THEN 
						x:=data2(15 downto 0);
						write(BUF,x);
						writeline(FILEOUT,BUF);
					END IF;
					end if;
				END PROCESS;	
					PROCESS_OUTDATA1:PROCESS(clk_l,enable)
				FILE FILEOUT: TEXT OPEN WRITE_MODE IS "outdata1.txt";    
				VARIABLE BUF:LINE;
				VARIABLE X:STD_uLOGIC;	
					BEGIN
					if enable = '1' then 
					IF clk_l'EVENT AND clk_l='1' THEN 
						x:=b;
						write(BUF,x);
						writeline(FILEOUT,BUF);
					END IF;
					end if;
				END PROCESS;	
--PROCESS_OUTDATA:PROCESS(clk1)
--				FILE FILEOUT: TEXT OPEN WRITE_MODE IS "outdata.txt";    
--				VARIABLE BUF:LINE;
--				VARIABLE X:STD_LOGIC;	
--					BEGIN
--					--IF rst2='0' then
--						--x:='Z';
--					IF clk1'EVENT AND clk1='1' THEN 
--						x:=testoutdata;
--						write(BUF,x);
--						writeline(FILEOUT,BUF);
--					END IF;
--				END PROCESS;

	
end rtl;
